home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d7 / hostplus.arc / LSRHOST.SLT next >
Text File  |  1990-04-22  |  32KB  |  1,154 lines

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. //   H O S T . S L T
  4. //
  5. //   Copyright (C) 1988 PTel and Colin Sampaleanu
  6. //
  7. //   This is a Host Mode for Telix, written as a script file.
  8. //   Ton configure Host Mode parameters such as passwords, run the 'HCONFIG'
  9. //   script. That script is run automatically if the Host Mode ocnfiguration
  10. //   file 'HOST.CNF' is missing.
  11. //
  12. //   This script will only work with Hayes compatible modems, but may be
  13. //   modified for operation with other modems.
  14. //
  15. //////////////////////////////////////////////////////////////////////////////
  16.  
  17. /////////////////////////////////////////////////////////////////////////////
  18. //
  19. //   MODIFICATION  NOTICE
  20. //   ------------  ------
  21. //
  22. //   This version of the Telix Host Script File has been modified by:
  23. //   Lawrence Stone, Lawrence Stone Research Group, April, 1990     -LSR
  24. //
  25. //   Note:  All modifications by me can be found by searching this script
  26. //   for the initials, "LSR".
  27. //
  28. //   The following are modifications to the original Host Script file:
  29. //
  30. //      1.  Requires level II password before caller can access the
  31. //          shell command.  Shell still needs separate password.
  32. //
  33. //      2.  Requires level II password before caller can access the
  34. //          shut down host command.  Still requires separate password.
  35. //
  36. //      3.  The do_one_caller routine would erroneously trap ARQ modems
  37. //          in the if expression, "if (!determine_baud())".  This was
  38. //          corrected by adding {} symbols below the if statement.  The
  39. //          original expression failed to work because there wasn't any
  40. //          command immediately below the if expression, only a remark
  41. //          to "do something here if this is a problem" (at least in my
  42. //          first copy of the host script).  The {} symbols properly define
  43. //          the limits of this if expression.
  44. //
  45. //      4.  When the caller shells to DOS, the original script would
  46. //          write a batch file to control the shell, call DOS to
  47. //          execute the batch, then, upon return to the program, close
  48. //          the file just written to.  Because the file was left open,
  49. //          Telix could not run it - the batch file must be closed first!
  50. //          Therefore, this script properly closes the file prior to
  51. //          having DOS run the batch.  (Note that new releases of Telix
  52. //          have corrected this error.)
  53. //
  54. //      5.  I discovered that if high speed, ARQ modems (HST, dual standard,
  55. //          etc.) are calling a non-hand shaking modem (like my 2400 baud)
  56. //          then, binary characters would dump into the current_caller
  57. //          string.  Worse, although you would see these characters from
  58. //          the host computer, the caller would not see anything, just a
  59. //          blinking cursor.  I corrected the script to work with ARQ modems
  60. //          by adding the command, type_file("SYNC.MSG") <included with this
  61. //          script> and by increasing the initial delay from 1/10 second to
  62. //          five seconds.  The SYNC.MSG file forces high speed modems to
  63. //          synchronize on it's text <ie, a substitute for a handshake> and
  64. //          the increase in delay time allows high speed modems to settle in.
  65. //          Note that callers using ARQ modems will *not* see the SYNC.MSG on
  66. //          their consoles but, non-ARQ callers *will* see this message!
  67. //          These changes are found in the do_one_caller routine.
  68. //
  69. //      6.  Added dooR option to menu.  This option requires that the user
  70. //          creates a batch file called, RSHELL.BAT to run the door program.
  71. //          It also requires level 2 password to access.
  72. //
  73. //      7.  Added automatic log enteries to the host log as soon as a
  74. //          call is received, and when ever a caller types any password,
  75. //          or tries to go to a DOS shell, or returns from a DOS shell,
  76. //          or tries to shut down the host mode.  Also logs when user
  77. //          enters or exits chat mode, lists any file, types any file, or
  78. //          attempts to access the door.  Each call received is now seper-
  79. //          ated by a 47 character string of "=" symbols.  This allows easy
  80. //          recognition of each call received while listing the log.
  81. //
  82. //      8.  Added PUMA external transfer protocal.  Added automatic log
  83. //          enteries whenever the user starts and ends Puma transfers.
  84. //
  85. /////////////////////////////////////////////////////////////////////////////
  86.  
  87. // Parameters which can be configured
  88.  
  89. str pass1[8] = "host",                  // The level 1 pass
  90.     pass2[8] = "host2",                 // The level 2 pass
  91.     shellpass[8] = "shell",             // the pass to enter the Remote Shell
  92.     shutpass[8] = "shut",               // the pass to shut down the Host Mode
  93.     host_downloads[64],                 // where users may download from
  94.     host_uploads[64];                   // where uploaded files go
  95.  
  96. int direct_connect = 0;
  97.  
  98. str current_caller[31],                 // storage of current caller's name
  99.     conn300[] = "CONNECT^M",            // modem result messages for bauds
  100.     conn1200[] = "CONNECT 1200",
  101.     conn2400[] = "CONNECT 2400",
  102.     conn9600[] = "CONNECT 9600",
  103.     conn19200[] = "CONNECT 19200";
  104.  
  105. int finished_caller,                    // set to TRUE when must return to top
  106.     local_mode,                         // set to TRUE when local test mode
  107.     access_level,                       // access level of current caller
  108.     carrier_counts = 1,                 // TRUE if should watch Carrier signal
  109.     already_connected = 0,
  110.     exit_requested = 0,                 // set to TRUE if Sysop has pressed Esc
  111.     connection_lost = 0,                // set to TRUE when carrier lost
  112.     kill_user = 0;                      // set to TRUE when user must be purged
  113.  
  114. int old_scr_chk_key,                    // storage for some system variables
  115.     old_cisb_auto,                      // which we have to modify and put
  116.     old_zmod_auto,                      // back to what they were when done
  117.     old_sound;
  118.  
  119. str old_down_dir[64],
  120.     old_up_dir[64];
  121.  
  122. //////////////////////////////////////////////////////////////////////////////
  123. //////////////////////////////////////////////////////////////////////////////
  124.  
  125. main()
  126.  
  127. {
  128.  int c;
  129.  
  130.  clear_scr();
  131.  
  132.  if (read_host_config_file() == -1)
  133.   {
  134.    prints("Unable to read HOST.CNF...");
  135.    prints("Running HCONFIG, the Host Mode configuration script.^M^J");
  136.    call("HCONFIG");
  137.    if (read_host_config_file() == -1)
  138.     {
  139.      prints("Still unable to read HOST.CNF. Aborting Host Mode.^M^J");
  140.      return -1;
  141.     }
  142.   }
  143.  
  144.  if (!check_directories())
  145.   {
  146.    prints("Either the upload or download directory as defined in the HOST.CNF file");
  147.    prints("doesn't exist. Either create the missing directory with the DOS 'MKDIR'");
  148.    prints("command, or run the HCONFIG script to redefine what directories to use.");
  149.    prints("Aborting Host Mode.");
  150.    return -1;
  151.   }
  152.  
  153.  old_scr_chk_key = _scr_chk_key;
  154.  _scr_chk_key = 0;
  155.  old_cisb_auto = _cisb_auto;
  156.  _cisb_auto = 0;
  157.  old_zmod_auto = _zmod_auto;
  158.  _zmod_auto = 0;
  159.  old_sound = _sound_on;
  160.  _sound_on = 0;
  161.  old_down_dir = _down_dir;
  162.  _down_dir = host_uploads;   // these are reversed because we are now the Host
  163.  old_up_dir = _up_dir;
  164.  _up_dir = host_downloads;   // these are reversed because we are now the Host
  165.  
  166.  usagelog("HOST.LOG");
  167.  
  168.  if (direct_connect)
  169.   carrier_counts = 0;
  170.  else
  171.   carrier_counts = 1;
  172.  
  173.  if (!direct_connect && carrier())
  174.   already_connected = 1;
  175.  
  176.  if (!direct_connect && !already_connected)
  177.   {
  178.    prints("Initializing modem");
  179.    cputs_tr(_auto_ans_str);
  180.   }
  181.  
  182.  while (1)
  183.   {
  184.    finished_caller = kill_user = 0;
  185.  
  186.    if (direct_connect)
  187.     carrier_counts = 0;
  188.    else
  189.     carrier_counts = 1;
  190.  
  191.    if (!direct_connect)
  192.     {
  193.      prints("^M^JHost Mode: Waiting for call...");
  194.      prints("(Press Esc to exit, or 'L' for local test mode).^M^J");
  195.  
  196.      do
  197.       {
  198.        if (carrier())
  199.         {
  200.          local_mode = 0;
  201.          break;
  202.         }
  203.  
  204.        c = inkey();
  205.        if (c)
  206.         {
  207.          if (c == 27)
  208.           {
  209.            exit_requested = 1;
  210.            break;
  211.           }
  212.          else if (c == 'l' || c == 'L')               // local test mode
  213.           {
  214.            prints("Local test mode entered");
  215.            local_mode = 1;
  216.            carrier_counts = 0;
  217.           }
  218.         }
  219.       }
  220.      while (toupper(c) != 'L');
  221.     }
  222.  
  223.    if (!exit_requested)
  224.     {
  225.      prints("Incoming call. Sysop: press Esc to exit, or END to terminate user.");
  226.  
  227.      do_one_caller();
  228.      if ((connection_lost || kill_user) && carrier_counts && carrier())
  229.       hangup();             // make sure nobody sneaks in
  230.     }
  231.    already_connected = 0;
  232.    if (exit_requested)
  233.     {
  234.      if (!carrier() && !direct_connect)
  235.       cputs_tr(_mdm_init_str);
  236.      _scr_chk_key = old_scr_chk_key;
  237.      _cisb_auto = old_cisb_auto;
  238.      _zmod_auto = old_zmod_auto;
  239.      _sound_on = old_sound;
  240.      _down_dir = old_down_dir;
  241.      _up_dir = old_up_dir;
  242.      prints("^M^JHost mode script finished.");
  243.      usagelog("*CLOSE*");
  244.      return 1;
  245.     }
  246.   }
  247. }
  248.  
  249. //////////////////////////////////////////////////////////////////////////////
  250.  
  251. do_one_caller()
  252.  
  253. {
  254.  str strn[80],
  255.      fname[64],
  256.                                         //  -LSR
  257.      puma_down[66] = "s ",              // Using PUMA for external protocal
  258.      puma_up[66] = "r ";                // Note that the user's download
  259.                                         // is actually PUMA's send command
  260.                                         // and upload is PUMA's receive!
  261.                                         //  -LSR
  262.  int option,
  263.      status,
  264.      c, i, i2, f;
  265.  
  266.  access_level = 1;
  267.  
  268.  if (already_connected)
  269.   prints("Already Connected!");
  270.  else if (carrier_counts)
  271.   {
  272.    if (!determine_baud())
  273.     {
  274.      // this should not be a problem - if it is then do something here.
  275.      // The {} symbols added to define the limits of the if expression. - LSR
  276.     }
  277.   }
  278.  
  279.  delay(50);                  // 5 second delay lets ARQ modems settle -LSR
  280.  type_file("SYNC.MSG");      // Allow ARQ modems to sync in through a short
  281.                              // script file -LSR
  282.  flushbuf();
  283.  type_file("LOGO.MSG");
  284.  while (1)
  285.   {
  286.    host_send("Please enter your full name: ");
  287.    host_input_strn(current_caller, 30);
  288.    host_send("^M^J");
  289.  
  290.    if (finished_caller)
  291.     return;
  292.  
  293.    if (strlen(current_caller) >= 5)
  294.     break;
  295.   }
  296.  
  297.                         // Let's clearly mark where the logon starts!  -LSR
  298.  ustamp("New Logon =====================================", 1, 1);
  299.  ustamp("Called by: ", 1, 0);   // Who's calling - even if s/he fails to type
  300.  ustamp(current_caller, 0, 1);  // the correct password, we need to know -LSR
  301.  
  302.  access_level = ask_for_pass(3, pass1, pass2);
  303.  
  304.  if (access_level)      // Did current_caller use a valid logon password? -LSR
  305.   ustamp("Valid logon by ", 1, 0);
  306.  else
  307.   ustamp("Invalid logon by ", 1, 0);
  308.  ustamp(current_caller, 0, 1);
  309.  
  310.  if (!access_level)
  311.   {
  312.    host_send("Goodbye!^M^J");
  313.    if (carrier_counts)
  314.     {
  315.      delay(10);
  316.      hangup();
  317.     }
  318.    return;
  319.   }
  320.  
  321.  type_file("WELCOME.MSG");
  322.  
  323.  while (1)
  324.   {
  325.    if (finished_caller)
  326.     return;
  327.  
  328.    host_send("^M^JFiles  Type  Upload  Download  dooR  Shell  Chat  Goodbye ? ");
  329.    host_input_strn(strn, 1);
  330.    option = toupper(subchr(strn, 0));
  331.    host_send("^M^J");
  332.  
  333.    if (option == 'F')                 // Files directory
  334.     {
  335.      if (access_level == 2)
  336.       {
  337.        host_send("Enter 'filespec' or press Return for *.*,^M^J: ");
  338.        host_input_strn(fname, 64);
  339.        host_send("^M^J");
  340.  
  341.        if (just_filename(fname))
  342.         {
  343.          strn = host_downloads;
  344.          strcat(strn, fname);
  345.         }
  346.        else
  347.         strn = fname;
  348.       }
  349.      else
  350.       {
  351.        strn = host_downloads;
  352.        strcat(strn, "*.*");
  353.       }
  354.        
  355.      ustamp("User listed files: ", 1, 0);   // Log which file(s) listed  -LSR
  356.      ustamp(strn, 0, 1);
  357.  
  358.      if (local_mode)
  359.       show_directory(strn, 0, carrier_counts);
  360.      else
  361.       show_directory(strn, 1, carrier_counts);
  362.      host_send("^M^J");
  363.     }
  364.    else if (option == 'T')            // Type a file
  365.     {
  366.      host_send("Type what file? ");
  367.      host_input_strn(strn, 64);
  368.      host_send("^M^J");
  369.      if (access_level != 2)             // if access 1, name and ext only
  370.       fnstrip(strn, 3, fname);
  371.      else
  372.       fname = strn;
  373.  
  374.      if (just_filename(fname))
  375.       {
  376.        strn = host_downloads;
  377.        strcat(strn, fname);
  378.        fname = strn;
  379.       }
  380.  
  381.      if (!filefind(fname, 0, strn))
  382.       {
  383.        host_send("Unable to find ");
  384.        host_send(fname);
  385.        continue;
  386.       }
  387.  
  388.      ustamp("User typed file: ", 1, 0);   //Log which file(s) were typed -LSR
  389.      ustamp(fname, 0, 1);
  390.      type_file(fname);
  391.     }
  392.    else if (option == 'G')            // Goodbye (Hang-up)
  393.     {
  394.      host_send("^M^JGoodbye!^M^J");
  395.      ustamp("User logged off.", 1, 1);
  396.      if (carrier_counts)
  397.       {
  398.        delay(10);
  399.        hangup();
  400.       }
  401.      return;
  402.     }
  403.    else if (option == 'C')            // Chat mode
  404.     {
  405.      prints("Sysop: Press Space to chat, any other key not to.^M^J");
  406.      c = 0;
  407.      _sound_on = 1;
  408.      for (i = 8; i && !c; --i)
  409.       {
  410.        if (carrier_counts && !carrier())
  411.         {
  412.          prints("^M^JConnection has been lost, call terminated.^M^J");
  413.          connection_lost = 1;
  414.          finished_caller = 1;
  415.          break;
  416.         }
  417.        cputc('^G');
  418.        tone(523, 20);
  419.        tone(659, 20);
  420.        tone(523, 20);
  421.        tone(659, 20);
  422.        tone(523, 20);
  423.        tone(659, 20);
  424.        for (i2 = 30; i2 && (c = inkey()) == 0; --i2)
  425.         delay(1);
  426.       }
  427.      _sound_on = 0;
  428.      if (finished_caller)
  429.       continue;
  430.      if (c != ' ' || !c)
  431.       {
  432.        host_send("Sorry, the Sysop is unavailable^M^J");
  433.        continue;
  434.       }
  435.      host_send("The sysop is here!^M^J");
  436.      ustamp("User entered Chat mode.", 1, 1);  //Log this activity  -LSR
  437.      chatmode(1);
  438.      ustamp("User exited Chat mode.", 1, 1);   //Log end of chat    -LSR
  439.     }
  440.    else if (option == 'U')            // User upload
  441.     {
  442.      option = host_get_prot();
  443.      if (!option)
  444.       continue;
  445.  
  446.      status = 1;
  447.      if (option == 'T' || option == 'M' || option == 'S' ||
  448.          option == 'Y' || option == 'Z' || option == 'E')
  449.       {
  450.        send_transfer_msg();
  451.        status = receive(option, "");
  452.       }
  453.      else
  454.       {
  455.        if (option == 'P')           // PUMA external transfer protocal  -LSR
  456.         {
  457.          if (!filefind("PUMA.EXE", 23, strn)) // Modify if not in Telix's
  458.           {                                   // subdirectory or pathed  -LSR
  459.            host_send("^M^JSorry - Puma Protocol is Not Installed!^M^J");
  460.            continue;
  461.           }
  462.         }
  463.  
  464.        host_send("Upload what file? ");
  465.        host_input_strn(strn, 48);
  466.        host_send("^M^J");
  467.        if (!strn)
  468.         continue;
  469.        if (access_level != 2)             // if access 1, name and ext only
  470.         fnstrip(strn, 3, fname);
  471.        else
  472.         fname = strn;
  473.  
  474.        if (just_filename(fname))
  475.         {
  476.          strn = host_uploads;
  477.          strcat(strn, fname);
  478.          fname = strn;
  479.         }
  480.  
  481.        if (filefind(fname, 23, strn))
  482.         host_send("File already exists!^M^J");
  483.        else
  484.         {
  485.          if (option == 'P')           // PUMA external transfer protocal  -LSR
  486.           {
  487.            strn = puma_up;
  488.            strupper(fname);            // Make fname upper case           -LSR
  489.            strcat(strn, fname);        // Concatenate the PUMA's argument -LSR
  490.            fname = strn;
  491.            ustamp("Download using Puma protocol.", 1, 1); // Log the protocal used-LSR
  492.            ustamp("++ File : ", 1, 0);  // Log file(s) received from user -LSR
  493.            ustamp(fname, 0, 1);
  494.            run("PUMA ", strn, 0);     // Run the external protocal, PUMA  -LSR
  495.            ustamp("Returned to Telix from Puma protocol.", 1, 1); // Log the return-LSR
  496.            continue;
  497.           }
  498.          else
  499.           {
  500.            send_transfer_msg();
  501.            status = receive(option, fname);
  502.           }
  503.         }
  504.       }
  505.      if (status == -2)                        // Carrier lost
  506.       connection_lost = finished_caller = 1;
  507.      else if (status == -1)
  508.       host_send("^GOne or more files not received!^M^J");
  509.     }
  510.    else if (option == 'D')            // User download
  511.     {
  512.      option = host_get_prot();
  513.      if (!option)
  514.       continue;
  515.  
  516.      if (option == 'P')           // PUMA external transfer protocal  -LSR
  517.       {
  518.        if (!filefind("PUMA.EXE", 23, strn)) // Modify if not in Telix's
  519.         {                                   // subdirectory or pathed  -LSR
  520.          host_send("^M^JSorry - Puma Protocol is Not Installed!^M^J");
  521.          continue;
  522.         }
  523.       }
  524.  
  525.      host_send("Download what file(s)? ");
  526.      host_input_strn(strn, 48);
  527.      host_send("^M^J");
  528.      if (!strn)
  529.       continue;
  530.      if (access_level != 2)      // if not level 2, keep only name & ext
  531.       fnstrip(strn, 3, fname);
  532.      else
  533.       fname = strn;
  534.  
  535.      if (just_filename(fname))
  536.       {
  537.        strn = host_downloads;
  538.        strcat(strn, fname);
  539.        fname = strn;
  540.       }
  541.  
  542.      if (!filefind(fname, 0, strn))
  543.       {
  544.        host_send("Unable to find any matching file(s)!^M^J");
  545.        continue;
  546.       }
  547.  
  548.     if (option == 'P')              // PUMA external transfer protocal  -LSR
  549.      {
  550.       strn = puma_down;
  551.       strupper(fname);              // Make fname upper case            -LSR
  552.       strcat(strn, fname);          // Concatenate the PUMA's argument  -LSR
  553.       fname = strn;
  554.       ustamp("Upload using Puma protocol.", 1, 1);  // Log the protocal used     -LSR
  555.       ustamp("++ File : ", 1, 0);  // Log the files sent to the user    -LSR
  556.       ustamp(fname, 0, 1);
  557.       run("PUMA ", strn, 0);        // Run the external protocal, PUMA  -LSR
  558.       ustamp("Returned to Telix from Puma protocol.", 1, 1); // Log the return-LSR
  559.       continue;
  560.      }
  561.  
  562.      status = 1;
  563.      send_transfer_msg();
  564.      status = send(option, fname);
  565.      if (status == -2)                        // Carrier lost
  566.       connection_lost = finished_caller = 1;
  567.      else if (status == -1)
  568.       host_send("^GOne or more files not received!^M^J");
  569.     }
  570.  
  571.    else if (option == 'R')           // Door - accessed via RSHELL.BAT   -LSR
  572.     {
  573.  
  574.      ustamp("Attempt to access Host Door Mode.", 1, 1); //Log attempt  -LSR
  575.  
  576.      if (access_level != 2)          // If you didn't use the host2 password
  577.       {                              // then you can't use the door      -LSR
  578.        host_send("^M^JYou do not have Door privileges - Access to Door is denied!^M^J");
  579.        ustamp("Attempt to access Host Door - Denied!", 1, 1);
  580.        continue;                     // Someone tried who shouldn't have -LSR
  581.       }                             
  582.  
  583.      if (get_baud() == 300)
  584.       delay(10);
  585.  
  586.      // See if user has prepared a custom file for door operation
  587.      // and call that if it exists                                      -LSR
  588.  
  589.      if (filefind("RSHELL.BAT", 0, strn))
  590.       {        // Let's track any access into DOS, even if it's a door  -LSR
  591.  
  592.        ustamp("Entered DOS shell - Custom Door File.", 1, 1);
  593.        dos("RSHELL.BAT", 0);
  594.        ustamp("Returned from Custom Door.", 1, 1); //How long in door?  -LSR
  595.       }
  596.      else
  597.       {
  598.        host_send("^M^JSorry Custom Door is Not Installed!^M^J");
  599.                                       // Log it, even if it failed.     -LSR
  600.        ustamp("Failed to open Custom Door batch file.", 1, 1);
  601.       }
  602.     }
  603.  
  604.    else if (option == 'S')            // Remote shell
  605.     {                                 // Log it from the get-go          -LSR
  606.      ustamp("Attempt to access DOS shell.", 1, 1); // Log the attemp     -LSR
  607.  
  608.      if (access_level != 2)          // If you didn't use the host2 password
  609.       {                              // then you can't use the shell     -LSR
  610.        host_send("^M^JYou do not have SysOp privileges - Access to shell is denied!^M^J");
  611.        ustamp("Attempt to access DOS shell - Denied!", 1, 1);
  612.       }                              // Someone tried who shouldn't have -LSR
  613.  
  614.      else if (ask_for_pass(3, shellpass, shellpass) != 0)
  615.       {
  616.        host_send("Type EXIT and then press Enter to come back.^M^J");
  617.        if (get_baud() == 300)
  618.         delay(10);
  619.        if (local_mode)
  620.         {
  621.          ustamp("Entered DOS shell - Local Mode.", 1, 1); // Track it!  -LSR
  622.          dos("", 0);
  623.          ustamp("Returned from DOS shell.", 1, 1);  // How long in shell? -LSR
  624.         }
  625.        else   // otherwise make our own temporary batch file for redirection
  626.         {
  627.  
  628.          // now want to make a temporary batch file which will be called
  629.          // to redirect DOS input and output, then shell to another copy
  630.          // of COMMAND.COM
  631.  
  632.          f = fopen("HOSTTEMP.BAT", "w");
  633.          if (f)
  634.           {
  635.            if (get_port() != 1 && get_port() != 2)
  636.             {
  637.              host_send("Remote Shell not supported on this comm port due to DOS limits!^M^J");
  638.              continue;
  639.             }
  640.  
  641.            strn = "COMx";
  642.            setchr(strn, 3, get_port() + '0'); // get right name to redirect
  643.  
  644.            fputs("CTTY ", f);            // write to batch file
  645.            fputs(strn, f);
  646.            fputs("^M^JCOMMAND ^M^J", f);
  647.            fputs("CTTY CON^M^J", f);
  648.            fputs("EXIT^M^J", f);
  649.            fclose(f);                   // close file *before* shelling! -LSR
  650.  
  651.            if (!local_mode)             // call batch file
  652.             {                           // Better track this one!  -LSR
  653.              ustamp("Entered DOS shell - Remote Access.", 1, 1);
  654.              dos("HOSTTEMP.BAT", 0);
  655.              ustamp("Returned from DOS shell.", 1, 1);
  656.             }                           // How long in the shell?  -LSR
  657.           }
  658.          else
  659.           {
  660.            host_send("Can't open temporary batch file!^M^J");
  661.                                         // Log it, even if it failed.  -LSR
  662.            ustamp("Failed to open batch file for the DOS shell.", 1, 1);
  663.           }
  664.         }
  665.       }
  666.     }
  667.  
  668.    // Shut down Host Mode *only* if logon was with host2 password -LSR
  669.    else if (option == '^Z' && access_level == 2)   
  670.     {
  671.      host_send("Shut down Host mode. ");
  672.      ustamp("Attempt to shut down host mode.", 1, 1); // Log this one!!  -LSR
  673.      if (!ask_for_pass(3, shutpass, shutpass))
  674.       {                          // Track it!  Someone is doing a no-no  -LSR
  675.        ustamp("Attempt to shut down Host Mode - Denied!", 1, 1);
  676.        continue;
  677.       }
  678.      host_send("Goodbye!^M^J");
  679.      if (carrier_counts)
  680.       hangup();
  681.      ustamp("User shut down Host Mode.", 1, 1);
  682.      finished_caller = 1;
  683.      exit_requested = 1;
  684.     }
  685.   }
  686. }
  687.  
  688. //////////////////////////////////////////////////////////////////////////////
  689.  
  690. host_get_prot()
  691.  
  692. {
  693.  str prot[1];
  694.  
  695.  host_send("^M^JModem7 SEAlink Xmodem 1k-Xmodem G-1k-Xmodem Ymodem YmodEm-g Zmodem Puma^M^J");
  696.  host_send("Which protocol? ");
  697.  host_input_strn(prot, 1);
  698.  host_send("^M^J");
  699.  
  700.  if (strposi("MSX1GYEZP", prot, 0) == -1)     // if illegal prot
  701.   prot = "";                                 // return 0
  702.  
  703.  return (toupper(subchr(prot, 0)));
  704.  
  705. }
  706.  
  707. //////////////////////////////////////////////////////////////////////////////
  708.  
  709. send_transfer_msg()
  710.  
  711. {
  712.  host_send("Ready to transfer file(s)... Press Ctrl-X at least twice to abort^M^J");
  713. }
  714.  
  715. //////////////////////////////////////////////////////////////////////////////
  716. // Determine the baud rate once a Carrier Detect Signal has been detected
  717. // Since no characters were read, the 'CONNECT' string should still be
  718. // in the receive buffer.
  719.  
  720. determine_baud()
  721.  
  722. {
  723.  int t3, t12, t24, t96, t192;
  724.  int tmark, stat;
  725.  int new_baud = 0;
  726.  
  727.  printsc("Determining baud... ");
  728.  
  729.  track_free(0);                // clear all existing tracks
  730.  
  731.  t3 = track(conn300, 0);       // check for connect strings
  732.  t12 = track(conn1200, 0);
  733.  t24 = track(conn2400, 0);
  734.  t96 = track(conn9600, 0);
  735.  t192 = track(conn19200, 0);
  736.  
  737.  tmark = timer_start(30);      // wait up to 3 seconds for string
  738.                              
  739.  while (!time_up(tmark))
  740.   {
  741.    if (!carrier())
  742.     {
  743.      track_free(0);            // clear all existing tracks
  744.      return 0;
  745.     }
  746.  
  747.    if (cinp_cnt())
  748.     track_addchr(cgetc());
  749.  
  750.    stat = track_hit(0);
  751.    if (stat == 0)
  752.     continue;
  753.  
  754.    if (stat == t3)
  755.     new_baud = 300;
  756.    else if (stat == t24)
  757.     new_baud = 2400;
  758.    else if (stat == t96)
  759.     new_baud = 9600;
  760.    else if (stat == t192)
  761.     new_baud = 19200;
  762.    else
  763.     new_baud = 1200;
  764.  
  765.    break;                      // have baud rate, get out
  766.   }
  767.  
  768.  if (!new_baud)                // time-up without CONNECT string
  769.   {
  770.    prints("Failed!");
  771.    track_free(0);              // clear all existing tracks
  772.    return 0;     
  773.   }
  774.  
  775.  printn(new_baud);
  776.  prints("");
  777.  set_cparams(new_baud, get_parity(), get_datab(), get_stopb());
  778.  
  779.  track_free(0);                // clear all existing tracks
  780.  return 1;                     // indicate success
  781.  
  782. }
  783.  
  784. //////////////////////////////////////////////////////////////////////////////
  785.  
  786. type_file(str fname)
  787.  
  788. {
  789.  int f;
  790.  str buf[100];
  791.  int ichar, lines_sent = 0;
  792.  
  793.  f = fopen(fname, "r");
  794.  if (!f)
  795.   return -1;
  796.  
  797.  host_send("^M^J");
  798.  
  799.  while (1)
  800.   {
  801.    if (carrier_counts)
  802.     if (!carrier())
  803.      {
  804.       connection_lost = 1;
  805.       finished_caller = 1;
  806.       fclose(f);
  807.       return 0;
  808.      }
  809.  
  810.    if (fgets(buf, 80, f) == -1)
  811.     {
  812.      fclose(f);
  813.      return 1;
  814.     }
  815.  
  816.    host_send(buf);
  817.    host_send("^M^J");
  818.    ++lines_sent;
  819.  
  820.    if (lines_sent >= 22)
  821.     {
  822.      lines_sent = 0;
  823.      host_send("[More]");
  824.      host_input();
  825.  
  826.      if (finished_caller)         // if user inactivity
  827.       {
  828.        fclose(f);
  829.        return 0;
  830.       }
  831.  
  832.      host_send("^H ^H^H ^H^H ^H^H ^H^H ^H^H ^H^H ^H");
  833.     }
  834.  
  835.    while (cinp_cnt())
  836.     {
  837.      ichar = cgetc();
  838.      if (ichar == '^C' || ichar == '^K')
  839.       {
  840.        host_send("^M^J");
  841.        fclose(f);
  842.        return 1;
  843.       }
  844.     }
  845.   }
  846. }
  847.  
  848. //////////////////////////////////////////////////////////////////////////////
  849.  
  850. host_send(str outstr)
  851.  
  852. {
  853.  
  854.  printsc(outstr);
  855.  if (!local_mode)
  856.   cputs(outstr);
  857.  
  858. }
  859.  
  860. //////////////////////////////////////////////////////////////////////////////
  861.  
  862. host_send_c(int chr)
  863.  
  864. {
  865.  
  866.  printc(chr);
  867.  if (!local_mode)
  868.   cputc(chr);
  869.  
  870. }
  871.  
  872. //////////////////////////////////////////////////////////////////////////////
  873.  
  874. host_input_strn(str buf, int maximum)
  875.  
  876. {
  877.  int i = 0, key;
  878.  
  879.  while (1)
  880.   {
  881.    key = host_input();
  882.    if (!key)                 // timeout or user disconnect
  883.     {
  884.      setchr(buf, 0, 0);      // set string to empty
  885.      return 0;               // indicate there is a problem
  886.     }
  887.  
  888.    if (key == '^M')
  889.     break;
  890.    if (key == 127 || key == 8)
  891.     {
  892.      if (i)
  893.       {
  894.        --i;
  895.        host_send_c(key);
  896.       }
  897.      continue;
  898.     }
  899.    if (i < maximum)
  900.     {
  901.      setchr(buf, i, key);
  902.      i = i + 1;
  903.     }
  904.    else
  905.     i = i + 1;
  906.   }
  907.  
  908.  if (i > maximum)
  909.   i = maximum;
  910.  
  911.  setchr(buf, i, '^0');
  912.  
  913.  if (subchr(buf, 0))
  914.   return 1;
  915.  else
  916.   return 0;
  917.  
  918. }
  919.  
  920. //////////////////////////////////////////////////////////////////////////////
  921.  
  922. host_input()
  923.  
  924. {
  925.  int c;
  926.  int t;
  927.  
  928.  t = timer_start(2400);         // 4 minutes inactivity allowed
  929.  
  930.  while (1)
  931.   {
  932.    if (time_up(t) && !direct_connect)
  933.     {
  934.      host_send("^M^J^M^JInactivity period too long. Connection terminated!^M^J");
  935.      if (carrier_counts)
  936.       hangup();
  937.      finished_caller = 1;
  938.      kill_user = 1;
  939.      return 0;
  940.     }
  941.  
  942.    if (carrier_counts)
  943.     if (!carrier())
  944.       {
  945.        prints("^M^JConnection has been lost, call terminated.^M^J");
  946.        connection_lost = 1;
  947.        finished_caller = 1;
  948.        return 0;
  949.       }
  950.  
  951.    if ((c = inkey()) != 0)
  952.     {
  953.      if (c == 27)               // ESC key, sysop wants to exit
  954.       {
  955.        finished_caller = 1;
  956.        exit_requested = 1;
  957.        return 0;
  958.       }
  959.      else if (c == 0x4f00)      // END key, temrinate user
  960.       {
  961.        prints("^M^JUser terminated!");
  962.        ustamp("User terminated!", 1, 1);
  963.        if (carrier_counts)
  964.         hangup();
  965.  
  966.        finished_caller = 1;
  967.        kill_user = 1;
  968.        return 0;
  969.       }
  970.  
  971.      else if (c <= 255)
  972.       {
  973.        if (c != 8 && c != 127)   
  974.         host_send_c(c);
  975.        return c;
  976.       }
  977.     }
  978.  
  979.    if (!local_mode)
  980.     if (cinp_cnt())
  981.      {
  982.       c = cgetc();
  983.       if (c != 8 && c != 127)
  984.        host_send_c(c);
  985.       return c;
  986.      }
  987.   }
  988. }
  989.  
  990. //////////////////////////////////////////////////////////////////////////////
  991.  
  992. ask_for_pass(int maxtries, str pass1, str pass2)
  993.  
  994. {
  995.  int i;
  996.  str strn[8];
  997.  
  998.  for (i = 0; i < maxtries; ++i)
  999.   {
  1000.    if (i)
  1001.     host_send("Wrong! Try again.^M^J");
  1002.    host_send("Password: ");
  1003.    host_input_strn(strn, 8);
  1004.    host_send("^M^J");
  1005.    ustamp("Typed Password: ", 1, 0);    //Log the password that was typed  -LSR
  1006.    ustamp(strn, 0, 1);
  1007.  
  1008.    if (finished_caller)
  1009.     return 0;
  1010.  
  1011.    if (!strcmpi(strn, pass1))
  1012.     return 1;
  1013.  
  1014.    if (!strcmpi(strn, pass2))
  1015.     return 2;
  1016.   }
  1017.  
  1018.  host_send("No more chances. Access denied.^M^J");
  1019.  
  1020.  return 0;
  1021.  
  1022. }
  1023.  
  1024. //////////////////////////////////////////////////////////////////////////////
  1025.  
  1026. read_host_config_file()
  1027.  
  1028. {
  1029.  str s[80];
  1030.  int f, stat;
  1031.  
  1032.  s = _telix_dir;
  1033.  strcat(s, "HOST.CNF");
  1034.  
  1035.  f = fopen(s, "r");
  1036.  if (!f)
  1037.   {
  1038.    printsc("Can't open ");
  1039.    prints(s);
  1040.    return -1;
  1041.   }
  1042.  
  1043.  stat = fgets(s, 80, f);
  1044.  if (stat == -1)
  1045.   goto got_error;
  1046.  pass1 = s;
  1047.  
  1048.  stat = fgets(s, 80, f);
  1049.  if (stat == -1)
  1050.   goto got_error;
  1051.  pass2 = s;
  1052.  
  1053.  stat = fgets(s, 80, f);
  1054.  if (stat == -1)
  1055.   goto got_error;
  1056.  shellpass = s;
  1057.  
  1058.  stat = fgets(s, 80, f);
  1059.  if (stat == -1)
  1060.   goto got_error;
  1061.  shutpass = s;
  1062.  
  1063.  stat = fgets(s, 80, f);
  1064.  if (stat == -1)
  1065.   goto got_error;
  1066.  host_downloads = s;
  1067.  
  1068.  stat = fgets(s, 80, f);
  1069.  if (stat == -1)
  1070.   goto got_error;
  1071.  host_uploads = s;
  1072.  
  1073.  stat = fgets(s, 80, f);
  1074.  if (stat == -1)
  1075.   goto got_error;
  1076.  direct_connect = (toupper(subchr(s, 0)) == 'D');
  1077.  
  1078.  fclose(f);
  1079.  return 1;
  1080.  
  1081. // jump here if error
  1082.  
  1083.  got_error:
  1084.   fclose(f);
  1085.   return -1;
  1086.  
  1087. }
  1088.  
  1089. //////////////////////////////////////////////////////////////////////////////
  1090.  
  1091. check_directories()
  1092.  
  1093. {
  1094.  str s[80];
  1095.  int i, a;
  1096.  
  1097.  // first remove trailing slashes
  1098.  
  1099.  s = host_uploads;
  1100.  i = strlen(s);
  1101.  if (i > 0)
  1102.   if (subchr(s, i - 1) == '\' || subchr(s, i - 1) == '/')
  1103.    setchr(s, i - 1, 0);
  1104.  if (s && !(strlen(s) == 2 && subchr(s, 1) == ':'))
  1105.   {
  1106.    a = fileattr(s);
  1107.    if (a == -1 || !(a & 16))
  1108.     return 0;                  // not a directory or doesn't exist
  1109.   }
  1110.  
  1111.  s = host_downloads;
  1112.  i = strlen(s);
  1113.  if (i > 0)
  1114.   if (subchr(s, i - 1) == '\' || subchr(s, i - 1) == '/')
  1115.    setchr(s, i - 1, 0);
  1116.  if (s && !(strlen(s) == 2 && subchr(s, 1) == ':'))
  1117.   {
  1118.    a = fileattr(s);
  1119.    if (a == -1 || !(a & 16))
  1120.     return 0;                  // not a directory or doesn't exist
  1121.   }
  1122.  
  1123.  return 1;
  1124.  
  1125. }
  1126.  
  1127. //////////////////////////////////////////////////////////////////////////////
  1128. // returns TRUE if passed filespec is just a filename. Also handles the
  1129. // forward slash as a path separator.
  1130.  
  1131. just_filename(str filespec)
  1132.  
  1133. {
  1134.  int slash, space;
  1135.  
  1136.  if (strpos(filespec, ":", 0) != -1)
  1137.   return 0;
  1138.  if (strpos(filespec, "\", 0) != -1)
  1139.   return 0;
  1140.  if ((slash = strpos(filespec, "/")) == -1)
  1141.   return 1;
  1142.  
  1143.  space = strpos(filespec, " ");
  1144.  if (space == -1)
  1145.   return 0;
  1146.  if (space < slash)
  1147.   return 1;
  1148.  
  1149.  return 0;
  1150.  
  1151. }
  1152.  
  1153. //////////////////////////////////////////////////////////////////////////////
  1154.